#usr/bin/python
import re
import sys

def vypisHran(self,hrany):	#samostatna metoda na vypisovani hran, stoji mimo tridy
	for i in hrany:
			print "h",i[0],i[1],i[2],i[3],
			sys.stdout.write(" :")
			print i[4]
			
def vypisUzlu(self,uzly): #samostatna metoda na vypis uzlu
	for i,j in uzly.items():
			print "u",i,j	

class grafData: #data grafu, jeho nacteni
	uzly={}
	hrany=[]
	file=""
	def vypisHran(self,hrany):	#samostatna metoda na vypisovani hran, stoji mimo tridy
		for i in hrany:
			print "h",i[0],i[1],i[2],i[3],
			sys.stdout.write(" :")
			print i[4]
			
	def vypisUzlu(self,uzly): #samostatna metoda na vypis uzlu
		for i,j in uzly.items():
			print "u",i,j
	
	
	def __init__(self,zdrojSoubor):	
		self.file=zdrojSoubor
		self.nacteni_grafu()
	def nacteni_grafu(self):
		uzel=re.compile(r"^u (\w+)( +(-?\d+))?$")
		hrana=re.compile(r"^h (\w+) +(<|-|>) +(\w+)( +(-?\d+))?( +:(.+))?$")
		
		data=sys.stdin.readlines()
	#f = open(self.file,'r')
		#data=f.readlines()
		for prvek in data:
			if re.match(hrana,prvek):
				h=hrana.search(prvek)
				pom=(h.group(1),h.group(2),h.group(3),h.group(5),h.group(7)) #cela hrana
				self.hrany.append(pom)
			if re.match(uzel,prvek):
				u=uzel.search(prvek)
				self.uzly[u.group(1)]=u.group(3)
			#=uzel.search(prvek)
	def vypis_uzly(self):
		vypisUzlu(self,self.uzly)
	def vypis_hrany(self):
		#print self.hrany[0][0]#pristup k prvku
		vypisHran(self,self.hrany) 

class vlastnostiGrafu(grafData): #funkcni vrstva 
	def __init__(self,file):
		grafData.__init__(self,file)

	def hasLoop(self):# funkcni a otestovane
		res=False
		for i in self.hrany:
			if i[0]==i[2]:
				res=True
		return res
	
	def isOriented(self):#funkcni a otestovane
		res=False
		for i in self.hrany:
			if i[1]==r"<":
				res=True
			elif i[1]==r">":
				res=True
		return res
		
	def degree(self,uzel,smer): #nebere smycku a jak brat smycku ? vstup i vystup?
		vystupni=0			# funkcni, vic otestovat
		vstupni=0
		neorientovane=0
		
		for i in self.hrany:
			if i[0]==uzel and i[2]==uzel:
				vstupni=vstupni+1
				vystupni=vystupni+1	
			elif i[0]==uzel and i[1]==">":
				vystupni=vystupni+1
			elif i[2]==uzel and i[1]=="<":
				vystupni=vystupni+1
			elif i[0]==uzel and i[1]=="<":
				vstupni=vstupni+1
			elif i[2]==uzel and i[1]==">":
				vstupni=vstupni+1
			elif i[0]==uzel or i[2]==uzel:
				if i[1]=="-":
					neorientovane=neorientovane+1
			
		if smer=="<":
			return vstupni
		elif smer==">":
			return vystupni
		else:
			return vstupni+vystupni+neorientovane
			
	def isRegular(self):
		pom=True
		stupen=self.degree(self.uzly.keys()[0],"") # prvni uzel co mam v seznamu uzlu
		for k in self.uzly.keys():
			if stupen != self.degree(k,""):
				pom=False
		return pom
	
	def surrounding(self,uzel,smer):
		pomHrany=[]
		vystup=[]
		for h in self.hrany:
			if h[0]==uzel or h[2]==uzel:
				pomHrany.append(h)
		
		if smer==">":
			for i in pomHrany:
				if i[1]==">":
					if i[0]==uzel:
						vystup.append(i)
				if i[1]=="<":
					if i[2]==uzel:
						vystup.append(i)
		if smer=="<":
			for i in pomHrany:
				if i[1]=="<":
					if i[0]==uzel:
						vystup.append(i)
				if i[1]==">":
					if i[2]==uzel:
						vystup.append(i)
		if smer=="" or smer=="-":
			vystup=pomHrany
						
		return vystup
	
	def isNotMultigraph(self):
		pom=0
		for h in self.hrany:
			for hi in self.hrany:	#prijit na lepsi zpusob jak to zapsat
				if h[0]==hi[0] and h[1]==">" and h[2]==hi[2]:
					pom=pom+1
				elif h[0]==hi[2] and h[1]=="<" and h[2]==hi[0]:
					pom=pom+1
				elif h[0]==hi[0] and h[1]=="<" and h[2]==hi[2]:
					pom=pom+1
				elif h[0]==hi[2] and h[1]==">" and h[2]==hi[0]:
					pom=pom+1
				elif h[0]==hi[2] and h[1]=="-" and h[2]==hi[0]:
					pom=pom+1
				elif h[0]==hi[0] and h[1]=="-" and h[2]==hi[2]:
					pom=pom+1
	  
	  	if len(self.hrany)!=pom:
	  		return False
	  	else:
	  		return True
	  		
	def isComplete(self):
		if self.isSimple():
			pass
		else:
			return 2
	  		
	def isSimple(self):
	  	if self.isNotMultigraph() and not(self.hasLoop()):
	  		return True
	  	else:
	  		return False
	
	def neighbors(self,uzel,smer):
		pomU=[]
		pomH=[]
		vystup={}
		
		for h in self.hrany:
			if h[0]==uzel or h[2]==uzel:
				pomH.append(h)
		
		if smer==">":
			for hx in pomH:
				if hx[0]==uzel and hx[1]==">":
					pomU.append(hx[2])
				if hx[2]==uzel and hx[1]=="<":
					pomU.append(hx[0])
		if smer=="<":
			for hx in pomH:
				if hx[0]==uzel and hx[1]=="<":
					pomU.append(hx[2])
				if hx[2]==uzel and hx[1]==">":
					pomU.append(hx[0])
		if smer=="" or smer=="-":
			for hz in pomH:
				if hz[0]==uzel:
					pomU.append(hz[2])
				else:
					pomU.append(hz[0])
		
		for i in pomU:
			vystup[i]=self.uzly[i]#pokud nemam ulozen uzel vyhazuje key exception error
	  		
	  	return vystup

		
		
class rozhrani:# rozhrani co zajistuje volani metod a vypisovani vlastnosti30%
# potom dodelat init na nacteni souboru ze stdin
	def __init__(self):
		self.a=vlastnostiGrafu("zdroj.txt")# ten textak je tam asi zbytecne ale asi ho tam uz necham
		self.a.vypis_uzly() #ok
		self.a.vypis_hrany() #ok
	
	def hasLoop(self): #ok
		if self.a.hasLoop():
			print "#!hasloop=true"
		else:
			print "#!hasloop=false"
	
	def isOriented(self):	#ok
		if self.a.isOriented():
			print "#!isOriented=true"
		else:
			print "#!isOriented=false"
	
	def isSimple(self): #asi ok
		if self.a.isSimple():
			print "#!isSimple=true"
		else:
			print "#!isSimple=false"
	
	def isNotMultigraph(self): #vic testu, pravdepodobne funguje
		if self.a.isNotMultigraph():
			print "#!isNotMultigraph=true"
		else:
			print "#!isNotMultigraph=false"
	
	def isSymetric(self):
		print "#!isSymetric=true"
		print "#!isSymetric=false"
	
	def isRegular(self): #ok
		if self.a.isRegular():
			print "#!isRegular=true"
		else:
			print "#!isRegular=false"
		
	def degree(self,uzel,smer): #ok
		N=self.a.degree(uzel,smer)
		print "#!degree=",N
		
	def surrounding(self,uzel,smer):	#ok, ale vic testu
		vypisHran(self,self.a.surrounding(uzel,smer))
		
	def subGraph(self, uzly):
		pass
		
	def isComplete(self): #reaguje jen na !isSimple
		pom=self.a.isComplete()
		if pom==1:
			print "#!isSimpleComplete=true";
		elif pom==0:
			print "#!isSimpleComplete=false";
		elif pom==2:
			print "#!isSimpleComplete=none";
		
	def neighbors(self,uzel,smer): # asi dobry, vic testu
		vypisUzlu(self,self.a.neighbors(uzel,smer))
		#print "#!neighbors"
		
	def isBiparit(self):
		print "#!isBiparit=true"
		print "#!isBiparit=false"
		

	
r=rozhrani()

r.hasLoop()
r.isOriented()
r.degree("A",">")
r.isRegular()
r.isNotMultigraph()
r.isSimple()
r.isComplete()#dodelat 
r.surrounding("A",">")
r.neighbors("A","")

print "hlavni"




